package iit.projects.etaxi.model.service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


import iit.projects.etaxi.model.dao.VehicleDao;
import iit.projects.etaxi.model.entity.Driver;
import iit.projects.etaxi.model.entity.Vehicle;
import iit.projects.etaxi.model.entity.VehicleLocation;
import iit.projects.etaxi.util.Constants;

@Transactional(readOnly = true)
public class VehicleServiceImpl implements VehicleService {

	private VehicleDao vehicleDao;
	
	private int waitingTime;
	
	@Override
	public List<Vehicle> findVehicles() {
		return vehicleDao.findVehicles();
	}

	/**
	 * @param vehicleDao the vehicleDao to set
	 */
	public void setVehicleDao(VehicleDao vehicleDao) {
		this.vehicleDao = vehicleDao;
	}

	/**
	 * @return the vehicleDao
	 */
	public VehicleDao getVehicleDao() {
		return vehicleDao;
	}
	
	@Override
	@Transactional(readOnly=false, propagation=Propagation.REQUIRES_NEW)
	public void saveDriver(Driver driver){
		vehicleDao.saveDriver(driver);
	}
	
	@Override
	@Transactional(readOnly=false, propagation=Propagation.REQUIRES_NEW)
	public void processFinishedJobs(){
		Calendar calendar = Calendar.getInstance();
		calendar.roll(Calendar.MINUTE, -waitingTime);
		
		List<VehicleLocation> vehicleLocations = 
			vehicleDao.findVehicleLocationsByStatusByReservationStatusBefore(Constants.VehicleLocationStatus.LAST_ASSIGNED,
					Constants.ReservationStatus.COMPLETED, calendar.getTime());
		
		if(vehicleLocations != null && !vehicleLocations.isEmpty()){
			
			List<Vehicle> updatedVehicles = new ArrayList<Vehicle>();
			List<VehicleLocation> deletingVehicleLocations = new ArrayList<VehicleLocation>();
			
			for(VehicleLocation vehicleLocation : vehicleLocations){
				Vehicle vehicle = vehicleLocation.getVehicle();
				deletingVehicleLocations.addAll(vehicle.getVehicleLocations());
				vehicle.setVehicleLocations(null);
				vehicle.setOnHire(false);
				
				updatedVehicles.add(vehicle);
				
			}
			vehicleDao.deleteVehicleLocations(deletingVehicleLocations);
			vehicleDao.updateVehicles(updatedVehicles);
		}
	}

	public int getWaitingTime() {
		return waitingTime;
	}

	public void setWaitingTime(int waitingTime) {
		this.waitingTime = waitingTime;
	}

}
